package controller;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.activiti.engine.task.Task;

import wfm.activiti.ActivitiManager;
import wfm.activiti.util.TaskIdComparator;
import wfm.entities.Address;
import wfm.entities.Customer;
import wfm.entities.Ticket;
import wfm.entities.User;
import wfm.entities.WFInfo;
import wfm.query.QueryDao;

import com.constants.Constants;
import com.web.util.WebUtils;


@ManagedBean(name="ticketController")
@SessionScoped
public class TicketController {
	
	@ManagedProperty(value = "#{user}")
	private User user;
	
	@ManagedProperty(value = "#{wfInfo}")
	private WFInfo wfInfo;
	
	private Customer customer; 
	private Ticket ticket;
	
	@PostConstruct
	public void init(){
		//fetch data if some exist
		if(wfInfo.getTaskId()!=null){
			Task task = QueryDao.getTaskById(wfInfo.getTaskId());
			this.ticket = (Ticket) QueryDao.getVariableToProcessWithTask(task, "ticket");	
			if(ticket!=null)
				this.customer = ticket.getCustomer();
			else{
				this.ticket=new Ticket();
				this.ticket.setCustomer(new Customer());
			}
				
		}
	}
	
	/**
	 * Returns the UserGroup of the logged-in User
	 * @return
	 */
	private String getActUserGroup(){
		
		String userGroup=User.GROUP_DESKTOPWORKER;
		
		if(this.user!=null){
			userGroup = this.user.getUserGroup();
		}
		
		return userGroup;
	}
	
	/**
	 * Starts a new Process
	 * @return
	 */
	public String create(){		
		
		//FIXME: wieder zuruecksetzen
		this.ticket = new Ticket();
		this.ticket.setCustomer(new Customer("Max", "Muster", "Karlsplatz 13", "Wien", "1040", "Österreich", "1234567", "max@muster.at"));

					
		try{
			ActivitiManager manager = ActivitiManager.getInstance();
			manager.deployProcess(Constants.DEPLOY_PROCESS);
		    
			this.setInstanceId(manager.startProcess());
			
			List<Task> tasks=QueryDao.getAllTasks();
			
			Task t=null;
			
			if(tasks.size()>0){
				Collections.sort(tasks,new TaskIdComparator());
				t=tasks.get(0);  //holt sich letzten Task
				this.setTaskId(t.getId());
				QueryDao.setAssigneeToTask(t, this.getUser().getName());
				//FIXME
				//QueryDao.saveVariableToProcessWithTask(t,"test", "Hallo");
				//QueryDao.setAssigneeToTask(t, user.getUserName());
			}		
			
		}catch(RuntimeException t) {
			t.printStackTrace();
		}
		
		return WebUtils.redirect("ticketCreation");
	}
	

	/**
	 * Abort TicketCreation -> Kill generated Process
	 * @return
	 */
	public String abortTicket(){

		Task t=QueryDao.getTaskById(this.getTaskId());
	
		if(t!=null){
			QueryDao.abortProcess(t);
		}
		
		return WebUtils.redirect("myTasks");
	}
	
	/**
	 * Control if address exists via webService and save ticket.
	 * @return Navigation-String from Activity
	 */
	public String saveTicket(){
		
		String nextPage = "";
		
		String instanceId=this.getInstanceId();
		this.ticket.setId(Integer.parseInt(instanceId));
		QueryDao.saveVariableToProcessById(instanceId, "ticket", this.getTicket());
		
		Customer customer = this.getTicket().getCustomer();
		
		// Retrieving form fields
		Map<String, String> prop = new HashMap<String, String>();
		prop.put("street", customer.getAddress().getStreet());
		prop.put("zip", customer.getAddress().getZip());
		prop.put("city", customer.getAddress().getCity());
		prop.put("country", customer.getAddress().getCountry());
		
		// Retrieving Activiti engine
		ActivitiManager manager = ActivitiManager.getInstance();	

		try {
			// Submitting task form -> go to next Activity
			String taskId = this.getTaskId();
			manager.getProcessEngine().getFormService().submitTaskFormData(taskId, prop);

		} catch (Throwable t) {
			 t.printStackTrace();
			FacesContext fc = FacesContext.getCurrentInstance();
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR,"Problem with Webservice!!!", null);
			fc.addMessage(null, msg);
			fc.renderResponse();

			return "";
		}
		
		// Check for any execution errors
		
		String taskError = manager.getTaskError(instanceId);
		if (taskError != null && !taskError.equals(""))
		{	
			List<Task> tasks = manager.getProcessEngine().getTaskService().createTaskQuery().taskCandidateGroup(getActUserGroup()).processInstanceId(instanceId).list();
			if (tasks.size() > 0)
			{
				// Get first task
				Task task = tasks.get(0);
				this.setTaskId(task.getId());
				nextPage = QueryDao.getFormKey(this.getTaskId());
				QueryDao.setAssigneeToTask(task, this.getUser().getName());
			}
			
			FacesContext fc = FacesContext.getCurrentInstance();
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, taskError, null);
		    fc.addMessage(null, msg);
		    fc.renderResponse();
		}else{
				
			Address adr = null;
			//get Address from ProcessInstance
			adr = (Address) QueryDao.getVariableToProcessById(instanceId, "address");
			QueryDao.saveVariableToProcessById(instanceId, "ticket", this.getTicket());
			
			
			if(adr!=null){
				
				nextPage="myTasks";
				
				List<Task> tasks = manager.getProcessEngine().getTaskService().createTaskQuery().taskCandidateGroup(getActUserGroup()).processInstanceId(instanceId).list();
				if (tasks.size() > 0)
				{
					// Get first task
					Task task = tasks.get(0);
					this.setTaskId(task.getId());
					nextPage = QueryDao.getFormKey(this.getTaskId());
					QueryDao.setAssigneeToTask(task, this.getUser().getName());
				}
				
			}else{
				
				List<Task> tasks = manager.getProcessEngine().getTaskService().createTaskQuery().taskCandidateGroup(getActUserGroup()).processInstanceId(instanceId).list();
				if (tasks.size() > 0)
				{
					// Get first task
					Task task = tasks.get(0);
					this.setTaskId(task.getId());
					QueryDao.setAssigneeToTask(task, this.getUser().getName());
					
					//FIXME
					//nextPage = QueryDao.getFormKey(this.getTaskId());
					System.out.println("ADR Null nextPage: " + nextPage);
					this.setTaskId(task.getId());
				}
				
				FacesContext fc = FacesContext.getCurrentInstance();
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "No valid Address.", null);
			    fc.addMessage(null, msg);
			    fc.renderResponse();

			}
			
		}
		
		return WebUtils.redirect(nextPage);
	}

	public Ticket getTicket() {
		return ticket;
	}

	public void setTicket(Ticket ticket) {
		this.ticket = ticket;
	}
	public User getUser() {
		return user;
	}
	
	public void setUser(User user){
		this.user = user; 
	}
	
	public Customer getCustomer() {
		return this.customer;
	}

	public void setCustomers(Customer customer) {
		this.customer = customer;
	}
	
	public WFInfo getWfInfo() {
		return wfInfo;
	}

	public void setWfInfo(WFInfo wfInfo) {
		this.wfInfo = wfInfo;
	}

	public String getInstanceId() {
		return this.wfInfo.getInstanceId();
	}

	public void setInstanceId(String instanceId) {
		this.wfInfo.setInstanceId(instanceId);
	}

	public String getTaskId() {
		return this.wfInfo.getTaskId();
	}

	public void setTaskId(String taskId) {
		this.wfInfo.setTaskId(taskId);
	}
	
}
